import { ref } from 'vue'

export interface LocationData {
  latitude: number // 纬度
  longitude: number // 经度
  address?: string
  city?: string
  province?: string
}

// 修正：定义更精确的地址信息类型
interface AddressInfo {
  name: string
  address: string
  latitude: number
  longitude: number
  city?: string // 可选字段
  province?: string // 可选字段
  [key: string]: any // 其他可能的字段
}

// 状态管理
const location = ref<LocationData | null>(null)
const error = ref<string | null>(null)
const isLoading = ref(false)

const checkLocationPermission = (): Promise<boolean> => {
  return new Promise((resolve) => {
    uni.getSetting({
      success(res) {
        resolve(!!res.authSetting['scope.userLocation'])
      },
      fail() {
        resolve(false)
      },
    })
  })
}

/**
 * 请求定位权限
 * @returns Promise<boolean> 是否授权成功
 */
const requestLocationPermission = (): Promise<boolean> => {
  return new Promise((resolve) => {
    uni.authorize({
      scope: 'scope.userLocation',
      success() {
        resolve(true)
      },
      fail() {
        // 用户拒绝了授权
        resolve(false)
      },
    })
  })
}

/**
 * 引导用户打开设置页面授权
 */
const openSettingForPermission = (): Promise<boolean> => {
  return new Promise((resolve) => {
    uni.showModal({
      title: '提示',
      content: '需要位置权限才能使用定位功能，是否去设置开启？',
      success(res) {
        if (res.confirm) {
          uni.openSetting({
            success(settingRes) {
              resolve(!!settingRes.authSetting['scope.userLocation'])
            },
            fail() {
              resolve(false)
            },
          })
        } else {
          resolve(false)
        }
      },
    })
  })
}

/**
 * 确保定位权限已被授权
 * @returns Promise<void> 如果授权成功则 resolve，否则 reject
 */
const ensureLocationPermission = async (): Promise<void> => {
  const hasPermission = await checkLocationPermission()
  if (!hasPermission) {
    const permissionGranted = await requestLocationPermission()
    if (!permissionGranted) {
      const settingGranted = await openSettingForPermission()
      if (!settingGranted) {
        throw new Error('用户拒绝授权位置信息')
      }
    }
  }
}

/**
 * 获取原始位置信息（确保已授权）
 * @returns Promise<LocationData>
 */
const getRawLocation = async (): Promise<LocationData> => {
  isLoading.value = true
  error.value = null

  try {
    // 1. 确保权限已授权
    await ensureLocationPermission()

    // 2. 获取位置
    const position = await new Promise<UniApp.GetLocationSuccess>(
      (resolve, reject) => {
        uni.getLocation({
          type: 'wgs84',
          success: resolve,
          fail: (err) => {
            console.error('获取位置失败:', err)
            reject(err)
          },
        })
      },
    )

    // 3. 返回位置数据
    return {
      latitude: position.latitude,
      longitude: position.longitude,
    }
  } catch (err) {
    console.error('获取位置失败:', err)
    error.value = '获取位置信息失败，请检查是否已授权'
    throw err
  } finally {
    isLoading.value = false
  }
}

/**
 * 获取当前位置信息
 * @returns Promise<LocationData>
 */
const getCurrentLocation = async (): Promise<LocationData> => {
  isLoading.value = true
  error.value = null

  try {
    // 1. 确保定位权限已授权
    await ensureLocationPermission()

    // 2. 获取位置
    const position = await new Promise<UniApp.GetLocationSuccess>(
      (resolve, reject) => {
        uni.getLocation({
          type: 'wgs84',
          altitude: true,
          success: resolve,
          fail: reject,
        })
      },
    )

    // 3. 逆地理编码获取地址信息
    const addressInfo = await new Promise<AddressInfo>((resolve, reject) => {
      uni.chooseLocation({
        latitude: position.latitude,
        longitude: position.longitude,
        success: (res) => {
          const info: AddressInfo = {
            name: res.name || '',
            address: res.address || '',
            latitude: res.latitude,
            longitude: res.longitude,
            city: 'city' in res ? (res.city as string) : undefined,
            province: 'province' in res ? (res.province as string) : undefined,
          }

          resolve(info)
        },
        fail: reject,
      })
    })

    // 4. 组合数据
    const locationData: LocationData = {
      latitude: addressInfo.latitude,
      longitude: addressInfo.longitude,
      address: addressInfo.address,
      city: addressInfo.city,
      province: addressInfo.province,
    }

    location.value = locationData
    return locationData
  } catch (err) {
    console.error('获取位置失败:', err)
    error.value = '获取位置信息失败，请检查是否已授权'
    throw err
  } finally {
    isLoading.value = false
  }
}

// 导出hook
export const useLocation = () => {
  return {
    location,
    error,
    isLoading,
    getCurrentLocation,
    checkLocationPermission,
    getRawLocation,
    openSettingForPermission,
  }
}
